package server.util.mod;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import server.server.Server;
import server.server.User;

public class ModManager {
    private final String _path;
    private URLClassLoader _loader;
    private final Map<String, ModBase> _mods;

    private final Vector<ModBase> _connectedListeners;
    private final Vector<ModBase> _disconnectedListeners;
    private final Vector<ModBase> _receivedListeners;

    public ModManager(String modDir) {
        _mods = new HashMap<>();
        _connectedListeners = new Vector<>();
        _disconnectedListeners = new Vector<>();
        _receivedListeners = new Vector<>();

        _path = modDir;
    }

    public Set<String> getNames() {
        return _mods.keySet();
    }

    public Collection<ModBase> getMods() {
        return _mods.values();
    }

    public ModBase getMod(String name) {
        return _mods.get(name);
    }

    // 加载并注册所有模组
    // 返回-1表示加载过程中出现错误
    public int loadAll() {
        File modsPath = new File(_path);

        if (!(modsPath.exists() && modsPath.isDirectory())) {
            System.out.println("【模组管理器】 未找到模组文件夹！");
            return -1;
        }
        File[] classFiles = modsPath.listFiles(pathname -> pathname.getName().endsWith(".class"));

        try {
            _loader = new URLClassLoader(new URL[] { modsPath.toURI().toURL() });
            if (classFiles != null) {
                for (File file : classFiles) {
                    if (file.isFile()) {
                        String className = file.getAbsolutePath();
                        className = className.substring(modsPath.getAbsolutePath().length() + 1, className.length() - 6);
                        className = className.replace(File.separatorChar, '.');
                        try {
                            Class<?> c = _loader.loadClass(className);
                            for (Class<?> inters : c.getInterfaces()) {
                                if (inters.equals(ModBase.class)) {
                                    ModBase m = (ModBase) c.newInstance();
                                    _mods.put(m.listenStr(), m);
                                    System.out.println("【模组管理器】 已加载模组【" + className + "】 将对指令【" + m.listenStr() + "】进行监听！");

                                    if ((m.eventRegister() & ModBase.CONNECTED) != 0) {
                                        _connectedListeners.add(m);
                                        System.out.println("【模组管理器】 模组【" + className + "】已经注册了对“用户连接”事件的监听");
                                    }
                                    if ((m.eventRegister() & ModBase.DISCONNECTED) != 0) {
                                        _disconnectedListeners.add(m);
                                        System.out.println("【模组管理器】 模组【" + className + "】已经注册了对“用户断开连接”事件的监听");
                                    }
                                    if ((m.eventRegister() & ModBase.RECEIVED) != 0) {
                                        _receivedListeners.add(m);
                                        System.out.println("【模组管理器】 模组【" + className + "】已经注册了对“用户发送消息”事件的监听");
                                    }

                                    break;
                                }
                            }
                        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException ignored) {}
                    }
                }
            }
        } catch (MalformedURLException e) {
            return -1;
        }
        return _mods.size();
    }

    // 重新加载所有模组
    public int reloadAll() {
        _mods.clear();
        _connectedListeners.clear();
        _disconnectedListeners.clear();
        _receivedListeners.clear();

        try {
            _loader.close();
        } catch (IOException e) {
            //Do nothing
        }
        return loadAll();
    }

    // 执行模组
    public boolean execMod(String msg, Server server, User sender) {

        String[] arr = msg.split("\\s+");
        ModBase mod = _mods.get(arr[0]);
        if (mod == null) {
            return false;
        } else {
            mod.exec(arr, server, sender);
            return true;
        }
    }

    // 用户连接事件
    public boolean connected(Server server, User user) {
        boolean ret = true;
        for (ModBase lis : _connectedListeners) {
            ret = ret & lis.onUserConnected(server, user);
        }
        return ret;
    }

    // 用户断开连接事件
    public boolean disconnected(Server server, User user) {
        boolean ret = true;
        for (ModBase lis : _disconnectedListeners) {
            ret = ret & lis.onUserDisconnected(server, user);
        }
        return ret;
    }

    // 用户发送消息事件
    public boolean received(String msg, Server server, User user) {
        boolean ret = true;
        for (ModBase lis : _receivedListeners) {
            ret = ret & lis.onUserMsgReceived(msg, server, user);
        }
        return ret;
    }
}